# -*-coding:utf-8-*-
from datetime import datetime
from decimal import Decimal

from django.db import transaction
from django_redis import get_redis_connection
from rest_framework import serializers
from rest_framework.exceptions import ValidationError

from books.models import Books
from orders.models import OrderInfo, OrderBooks
from utils.exceptions import logger


class CollectBookSerializer(serializers.ModelSerializer):
    """
    我的收藏商品数据序列化起
    """
    duration = serializers.IntegerField(label='借阅时长')

    class Meta:
        model = Books
        fields = ('id', 'name', 'image_url', 'price', 'duration')

class OrderSettlementSerializer(serializers.Serializer):
    """
    订单结算数据序列化器
    序列化器的嵌套
    """
    freight = serializers.DecimalField(label='运费', max_digits=10, decimal_places=2)
    books = CollectBookSerializer(many=True)


class SaveOrderSerializer(serializers.ModelSerializer):
    """
    下单数据序列化器
    """
    class Meta:
        model = OrderInfo
        fields = ('order_id', 'address', 'pay_method')
        read_only_fields = ('order_id',)
        extra_kwargs = {
            'address': {
                'write_only': True,
                'required': True,
            },
            'pay_method': {
                'write_only': True,
                'required': True
            }
        }

    # @transaction.atomic()
    def create(self, validated_data):
        """保存订单"""
        # 获取当前下单用户
        user = self.context['request'].user

        address = validated_data['address']
        pay_method = validated_data['pay_method']
        # 生成订单编号
        order_id = datetime.now().strftime('%Y%m%d%H%M%S') + '%06d' % user.id

        with transaction.atomic():
            # 创建保存点
            save_ponit = transaction.savepoint()
            try:
                # 生成订单的基本信息
                order = OrderInfo.objects.create(
                        order_id=order_id,
                        user=user,
                        address=address,
                        total_count=0,
                        total_amount=Decimal(0),
                        freight=Decimal(10),
                        pay_method=pay_method,
                        status=OrderInfo.ORDER_STATUS_ENUM['UNSEND'] if pay_method == OrderInfo.PAY_METHODS_ENUM['CASH'] else OrderInfo.ORDER_STATUS_ENUM['UNPAID']

                )
                # 查询选中状态的图书对象
                redis_conn = get_redis_connection('collect')
                # 获取hash book_id和duration(时长)
                book_id_duration = redis_conn.hgetall('collect_{}'.format(user.id))
                collect = {}
                for book_id, duration in book_id_duration.items():
                    collect[int(book_id)] = int(duration)

                # 获取set集合
                book_ids = redis_conn.smembers('collect_selected_{}'.format(user.id))
                # 根据集合中的book_id获取商品对象
                for book_id in book_ids:
                    while True:

                        book = Books.objects.get(id=book_id)
                        old_borrow = book.borrow    # 员借阅量
                        book_duration = collect[book.id]

                        # TODO 判断当前借阅的图书书否已经在借阅中

                        if book.total < 1:
                            raise serializers.ValidationError('库存数量不足')

                        # 更新book中的借阅量
                        new_borrow = old_borrow + 1
                        ret = Books.objects.filter(id=book.id, borrow=old_borrow).update(borrow=new_borrow)
                        if ret == 0:
                            continue

                        # 更新订单基本信息表中总价和总量
                        order.total_amount += (book.price * book_duration)
                        order.total_count += 1

                        # 保存图书订单表

                        OrderBooks.objects.create(
                            order=order,
                            book=book,
                            duration=book_duration,
                            price=book.price
                        )
                        break

                # 更新总价
                order.total_amount += order.freight
                order.save()
            except Exception as e:
                transaction.savepoint_rollback(save_ponit)
                logger.error(e)

            else:
                transaction.savepoint_commit(save_ponit)
                # 删除缓存中的选中状态的图书
                pl = redis_conn.pipeline()
                pl.hdel('collect_{}'.format(user.id), *book_ids)
                pl.srem('collect_selected_{}'.format(user.id), *book_ids)
                pl.execute()
                # 返回结果
                return order


class BookSerializers(serializers.ModelSerializer):
    """订单图书序列化器"""
    # 数量
    duration = serializers.IntegerField(read_only=True)

    class Meta:
        model = Books
        fields = "__all__"


class OrdersSerializes(serializers.ModelSerializer):
    """订单表序列化器"""
    book = BookSerializers()

    class Meta:
        model = OrderBooks
        fields = "__all__"



class OrderListSerializers(serializers.ModelSerializer):
    books = OrdersSerializes(many=True)

    class Meta:
        model = OrderInfo
        fields = "__all__"

# 商品信息展示
class BookSSerializer(serializers.ModelSerializer):
    class Meta:
        model = Books
        fields = "__all__"


# 待评论订单信息展示
class OrderUncommentedSerializer(serializers.ModelSerializer):
    book = BookSSerializer()
    class Meta:
        model = OrderBooks
        fields = "__all__"


class CommentSaveSerializer(serializers.ModelSerializer):
    """保存商品评论"""
    class Meta:
        model = OrderBooks
        fields = "__all__"


